package com.ahdms.es.engine;

import com.ahdms.es.bean.SealInfo;
import com.ahdms.es.bean.enums.ApiCode;
import com.ahdms.es.exceptions.InvalidSealDateException;
import com.ahdms.es.exceptions.InvalidSealFormatException;
import com.ahdms.es.exceptions.InvalidSignedValueException;
import com.ahdms.es.exceptions.VerifySealException;
import com.ahdms.es.gm.v1.SESeal;
import com.ahdms.es.gm.v1.TBS_Seal;
import com.ahdms.es.util.DataConvert;
import org.bouncycastle.asn1.x509.Certificate;

import java.io.IOException;
import java.text.ParseException;
import java.util.Date;

/**
 * @author qinxiang
 * @date 2021-04-13 11:01
 */
public class SeSealGMVerifyEngine extends SeSealVerifyEngine {

    /**
     * 印章格式(国密标准)
     */
    private SESeal seSeal;

    /**
     * 制章人证书
     */
    private Certificate cert;

    private SealInfo sealInfo;

    public static SeSealGMVerifyEngine getInstance(SESeal seSeal) throws VerifySealException {
        try {
            if (seSeal != null) {
                return new SeSealGMVerifyEngine(seSeal);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new VerifySealException(ApiCode.SEAL_FORMART_FAIL);
    }

    public static SeSealGMVerifyEngine getInstance(byte[] seSealData) throws VerifySealException {
        try {
            if (seSealData != null) {
                return new SeSealGMVerifyEngine(seSealData);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new VerifySealException(ApiCode.SEAL_FORMART_FAIL);
    }

    public SeSealGMVerifyEngine(SESeal seSeal) {
        this.seSeal = seSeal;
        this.cert = Certificate.getInstance(this.seSeal.getSignInfo().getCert().getOctets());
//        this.sealInfo = DataConvert.toSealInfo(seSeal);
    }

    public SeSealGMVerifyEngine(byte[] seSealData) {
        this.seSeal = SESeal.getInstance(seSealData);
        this.cert = Certificate.getInstance(this.seSeal.getSignInfo().getCert().getOctets());
//        this.sealInfo = DataConvert.toSealInfo(seSeal);
    }


    /**
     * 验证电子印章签名值是否正确
     *
     * @throws IOException
     */
    @Override
    public void verifySignData() throws IOException, VerifySealException {

        String signatureAlgorithmId = seSeal.getSignInfo().getSignatureAlgorithm().getId();
        //国密版本的签名原文组装
        TBS_Seal tbsSeal = new TBS_Seal(seSeal.getEsealInfo(), seSeal.getSignInfo().getCert(), seSeal.getSignInfo().getSignatureAlgorithm());
        verifySignData(cert, signatureAlgorithmId, tbsSeal.getEncoded()
                , seSeal.getSignInfo().getSignData().getOctets());

    }

    /**
     * 验证电子印章的有效期
     *
     * @throws ParseException
     */
    @Override
    public void verifyDate() throws ParseException, VerifySealException {
        Date startDate = seSeal.getEsealInfo().getProperty().getValidStart().getDate();
        Date endDate = seSeal.getEsealInfo().getProperty().getValidEnd().getDate();
        Date nowDate = new Date();
        verifyDate(nowDate, startDate, endDate);
    }

    @Override
    public Certificate getCert() {
        return this.cert;
    }

    @Override
    public SealInfo getSealInfo() {
        return DataConvert.toSealInfo(seSeal);
    }
}
